package com.jevons.muffin.net;

import com.jevons.muffin.net.log.HttpLoggingInterceptor;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import retrofit2.Converter;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.converter.simplexml.SimpleXmlConverterFactory;


/**
 * Retrofit请求管理
 * @author linaisheng
 * Created at 2019/3/14.
 */

public class RetrofitServiceManager {

    private static final String TAG = RetrofitServiceManager.class.getSimpleName();

    private static final String HTTP_LOG_TAG = "HttpLog";

    private static final int DEFAULT_TIME_OUT = 15;  //超时时间5s
    private static final int DEFAULT_READ_TIME_OUT = 10;

    //构建模式
    private static RetrofitBuilder builder;

    private OkHttpClient okHttpClient;
    private OkHttpClient upOrDownloadHttpClient;

    //日志
    private HttpLoggingInterceptor loggingInterceptor;

    private Retrofit mRetrofit;
    private Retrofit downloadRetrofit;

    private RetrofitServiceManager(RetrofitBuilder retrofitBuilder) {


        //判断是否初始化
        if (retrofitBuilder == null) {
            throw new IllegalArgumentException("no init RetrofitServiceManager with RetrofitBuilder");
        }

        //基础Url
        String baseUrl = retrofitBuilder.baseUrl;

        //创建OkHttpClient
        OkHttpClient.Builder downloadBuilder = new OkHttpClient.Builder();
        downloadBuilder.connectTimeout(15, TimeUnit.SECONDS);       //连接超时时间
        downloadBuilder.writeTimeout(240, TimeUnit.SECONDS);        //写操作 超时时间
        downloadBuilder.readTimeout(240, TimeUnit.SECONDS);

        //创建OkHttpClient
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.connectTimeout(retrofitBuilder.connectTimeout, TimeUnit.SECONDS);     //连接超时时间
        builder.writeTimeout(retrofitBuilder.writeTimeout, TimeUnit.SECONDS);  //写操作 超时时间
        builder.readTimeout(retrofitBuilder.readTimeout, TimeUnit.SECONDS);


        //添加拦截器
        for (Interceptor interceptor : retrofitBuilder.interceptors) {
            builder.addInterceptor(interceptor);
            downloadBuilder.addInterceptor(interceptor);
        }

        //日志拦截器打印
        if (retrofitBuilder.isUseHttpLogging) {
            loggingInterceptor = new HttpLoggingInterceptor();
            //设置日志级别
            loggingInterceptor.setLevel(retrofitBuilder.level);
            //设置 Debug Log 模式
            builder.addInterceptor(loggingInterceptor);

            downloadBuilder.addInterceptor(loggingInterceptor);
        }


        upOrDownloadHttpClient = downloadBuilder.build();
        okHttpClient = builder.build();



        downloadRetrofit = new Retrofit.Builder()
                .client(upOrDownloadHttpClient)
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(retrofitBuilder.converterFactory)
                .baseUrl(baseUrl)
                .build();


        mRetrofit = new Retrofit.Builder()
                .client(okHttpClient)
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(SimpleXmlConverterFactory.create())
                .addConverterFactory(retrofitBuilder.converterFactory)
                .baseUrl(baseUrl)
                .build();
    }

    private static class SingletonHolder {
        private static RetrofitServiceManager INSTANCE = new RetrofitServiceManager(builder);
    }

    /**
     * 获取RetrofitServiceManager单例
     * @return
     */
    public static RetrofitServiceManager getInstance() {
        return SingletonHolder.INSTANCE;
    }

    /**
     * 重新生成单例
     * @param b
     */
    public static void updateInstance(RetrofitBuilder b) {
        builder = b;
        SingletonHolder.INSTANCE = new RetrofitServiceManager(builder);
    }


    /**
     * 获取对应的Service
     * @param service Service 的 class
     * @param <T>
     * @return
     */
    public <T> T create(Class<T> service) {
        return mRetrofit.create(service);
    }

    public <T> T createUpOrDownload(Class<T> service) {
        return downloadRetrofit.create(service);
    }

    /**
     * 设置日志打印级别
     * @param level
     */
    public void setLoggingInterceptorLevel(HttpLoggingInterceptor.Level level) {
        if (loggingInterceptor != null && loggingInterceptor.getPrintLevel() != level) {
            loggingInterceptor.setLevel(level);
        }
    }

    /**
     * 发送OkHttp请求
     * @param request
     * @return
     */
    public Call sendOkHttpRequest(Request request) {
        return okHttpClient.newCall(request);
    }

    /**
     * OkHttp下载
     * @param request
     * @return
     */
    public Call downloadRequest(Request request) {
        return upOrDownloadHttpClient.newCall(request);
    }

    /**
     * 初始化
     * @param b
     */
    public static void initRetrofit(RetrofitBuilder b) {
        builder = b;
    }

    public static final class RetrofitBuilder {

        private String baseUrl;
        private boolean isUseHttpLogging;
        private HttpLoggingInterceptor.Level level =
                HttpLoggingInterceptor.Level.SIMPLE;
        private List<Interceptor> interceptors;
        private Converter.Factory converterFactory;

        private int connectTimeout = DEFAULT_TIME_OUT;
        private int writeTimeout = DEFAULT_READ_TIME_OUT;
        private int readTimeout = DEFAULT_READ_TIME_OUT;

        public RetrofitBuilder(String baseUrl) {
            this.baseUrl = baseUrl;
            interceptors = new ArrayList<>();
            converterFactory = GsonConverterFactory.create();
        }

        /**
         * 添加拦截器
         * @param interceptor
         * @return
         */
        public RetrofitBuilder addInterceptor(Interceptor interceptor) {
            interceptors.add(interceptor);
            return this;
        }


        /**
         * 设置是否需要网络日志打印
         * 网络日志打印会造成某些网络请求结果不一样
         * @param isUse
         * @return
         */
        public RetrofitBuilder setUseHttpLogging(boolean isUse) {
            this.isUseHttpLogging = isUse;
            return this;
        }

        /**
         * 设置打印级别
         * @param level
         * @return
         */
        public RetrofitBuilder setLogLevel(HttpLoggingInterceptor.Level level) {
            this.level = level;
            return this;
        }

        /**
         * 设置Json解析方式
         * @param factory
         * @return
         */
        public RetrofitBuilder addConverterFactory(Converter.Factory factory) {
            this.converterFactory = factory;
            return this;
        }

        public RetrofitBuilder setConnectTimeout(int connectTimeout) {
            this.connectTimeout = connectTimeout;
            return this;
        }

        public RetrofitBuilder setWriteTimeout(int writeTimeout) {
            this.writeTimeout = writeTimeout;
            return this;
        }

        public RetrofitBuilder setReadTimeout(int readTimeout) {
            this.readTimeout = readTimeout;
            return this;
        }

    }
}
